package com.zany.util.xml;

import org.jdom.*;
import org.jdom.input.*;
import org.jdom.output.*;

import com.zany.util.ZanyErrorMsg;
import com.zany.util.ZanyException;
import com.zany.util.String.StringUtils;

import java.io.*;
import java.util.*;




public class XmlPkgImpl{
    protected Document xmlDoc = null; // 组装好的，或者解析出来的完整的xml文档

    protected Element transaction = null; // 文档的根节点

    protected final char PATHSPLIT = '/';

    /**
     * 根据返回报文字符串，构造一个xml文档
     *
     * @param buf
     * 报文中的xml串(开发阶段，如果使用模拟报文，则为模拟报文文件名称)
     */
    public XmlPkgImpl(String buf) throws ZanyException {
        try {
        	SAXBuilder sb = new SAXBuilder();
            xmlDoc = sb.build(new StringReader(buf));
            transaction = xmlDoc.getRootElement();
        } catch (Exception e) {
            e.printStackTrace();
            throw new ZanyException(ZanyErrorMsg.ERR_DEFAULT, "返回报文转化成xml文档失败！\n"+e.getMessage(),e);
        }
    }

    /**
     * 把经过Map打包的私有数据解开加入到xml文档中去
     *
     * @param priv
     *            报文私有部分数据
     * @return void
     */
    public void setPkgItem(Map ppi) throws ZanyException {
        try {
            if (ppi == null || ppi.isEmpty()) {
            	transaction.setText(" ");
            }

            Set keySet = ppi.keySet();
            for (Iterator it = keySet.iterator(); it.hasNext(); ) {
                String strKey = (String) it.next();
                if (ppi.get(strKey) != null && !"".equals((String) ppi.get(strKey))) {
                	transaction.addContent(new Element(strKey).setText((String) ppi.get(strKey)));
                } else {
                	transaction.addContent(new Element(strKey).setText(" "));
                }
            }
            // 由于gaps平台对于<a />格式不认识,所以如果是空的节点,则改成添加一个" "
        } catch (Exception e) {
            e.printStackTrace();
            throw new ZanyException(ZanyErrorMsg.ERR_DEFAULT, e.getMessage(),e);
        }
    }

    /**
     * 把Map结构的数据打包到Xml包中去.
     *
     * @param prvKey
     *            打包的Xml节点名
     * @param prvMap
     *            打包的Xml节点数据
     * @return Xml结点Element
     */

    public Element commPak(String prvKey, Map prvMap) {
        Element elem = new Element(prvKey);

        // 如果没有子节点,则置" ",以便GAPS平台阅读
        if (prvMap == null || prvMap.isEmpty()) {
            elem.setText(" ");
        }
        Iterator it = prvMap.keySet().iterator();
        while (it.hasNext()) {
            String key = (String) it.next();
            Object prvObj = prvMap.get(key);
            if (prvObj != null) {
                if (prvObj instanceof String) {
                    String prvStr = (String) prvObj;
                    if (prvStr.equals("")) {
                        elem.addContent(new Element(key).setText(" "));
                    } else {
                        elem.addContent(new Element(key).setText(prvStr));
                    }
                } else if (prvObj instanceof HashMap) {
                    Element elemChild = commPak(key, (HashMap) prvObj);
                    elem.addContent(elemChild);
                }

            } else {
                elem.addContent(new Element(key).setText(" "));
            }

        }
        return elem;
    }

    /**
     * xml文档转化为字符串
     *
     * @param xmlDoc xml文档
     * @return String 转换后的字符串
     */
    public String xml2String(Document xmlDoc) throws ZanyException {
        XMLOutputter otpt = new XMLOutputter();
        StringWriter out = new StringWriter();
        try {
            Format fmt = Format.getRawFormat();
            fmt.setEncoding("GB2312");
            otpt.setFormat(fmt);
            otpt.output(xmlDoc, out);
            out.close();
        } catch (Exception e) {
            throw new ZanyException(ZanyErrorMsg.ERR_DEFAULT, "xml转化到字符串失败！\n"+e.getMessage(),e);
        }
        return out.toString();
    }

    /**
     * 得到报文字串
     */
    public String getPkgString() throws ZanyException {
        String tmpStr = xml2String(xmlDoc);
        tmpStr = StringUtils.replace(tmpStr, "\r", "");
        tmpStr = StringUtils.replace(tmpStr, "\n", "");
        tmpStr = StringUtils.replace(tmpStr, "\"", "\'");
        return tmpStr;
    }

    /******************************************************************************)
     * 根据节点路径得到节点元素
     * @param dictPath 节点路径 例如："/pub/aaa" 注意不含根节点名(root)
     * @return Element 节点元素
     * @throws ZanyException
     */
    public Element getNode(String dictPath) throws ZanyException {
        Element tempEle = null, subEle = null;
        List list = null;
        int index = 2;
        try {
            String nodeName = StringUtils.GetItemfromStr(dictPath, index,PATHSPLIT);
            tempEle = transaction;
            while (!nodeName.equals("")) {
                subEle = null;
                list = tempEle.getChildren();
                for (Iterator it = list.iterator(); it.hasNext(); ) {
                    subEle = (Element) it.next();
                    if (subEle.getName().equals(nodeName)) {
                        break;
                    } else {
                        subEle = null;
                    }
                }
                if (subEle == null) {
                    return null;
                }
                index++;
                tempEle = subEle;
                nodeName = StringUtils.GetItemfromStr(dictPath, index,
                        PATHSPLIT);
            }
        } catch (Exception e) {
            throw new ZanyException(ZanyErrorMsg.ERR_DEFAULT, "xml转化到字符串失败！\n"+e.getMessage(),e);
        }
        return subEle;
    }

    /*
     * 根据节点元素得节点
     * @param ele 节点元素
     * @return 字符串
     */
    public String getNodeText(Element ele) {
        String nodeValue = null;
        if (ele == null)
            return "";
        nodeValue = ele.getTextTrim();
        return nodeValue;
    }

    /*
     * 根据dictPath路径获得节点
     * @param dictPath 节点路径 例如："/pub/aaa" 注意不含根节点名(root)
     * @return String 节点的字符串内容
     * @throws ZanyException
     */
    public String getNodeText(String dictPath) throws ZanyException {
        String nodeValue = null;
        try {
            Element ele = getNode(dictPath);
            nodeValue = getNodeText(ele);
        } catch (Exception e) {
            throw new ZanyException(ZanyErrorMsg.ERR_DEFAULT, "xml转化到字符串失败！\n"+e.getMessage(),e);
        }
        return nodeValue;
    }
    /*
   * 根据detailName节点获取该节点下的所有记录集，
   * 格式如：<root><respcode>响应码</respcode>....<datalist><data1><userid>用户ID</userid><username>用户名</username><orgid>机构号</orgid>..</data1><data2>..</data2>
   * 。。</datalist></root>,如果格式为另外，则可以子类的方式重写该方法。
   * @param detailName 节点名称 例如："datalist" 注意不含根节点名(root)
   * @return List 结果集
   * @throws ZanyException
   */
   public List getNodeList(String detailName) throws ZanyException {
	   List list = new ArrayList();
       Element tmpEle = null, parentEme = null, eMxUnit = null, childEme = null;
       Map tmpMap = null;
       tmpEle = transaction;
       parentEme = tmpEle.getChild(detailName);
       List tmpList = parentEme.getChildren();
       if ((tmpList != null) && (!tmpList.isEmpty())) {
           for (int i = 0; i < tmpList.size(); i++) {
               tmpMap = new HashMap();
               eMxUnit = (Element) tmpList.get(i);
               List child = eMxUnit.getChildren();
               if ((child != null) && (!child.isEmpty())) {
                   for (int j = 0; j < child.size(); j++) {
                       childEme = (Element) child.get(j);
                       String name = childEme.getName();
                       String value = childEme.getText();
                       tmpMap.put(name, value);
                   }
               }
               list.add(tmpMap);
           }
       }

       return list;
 }



    /*
     * 根据dictPath路径插入节点值
     * @param dictPath 节点路径 例如："/pub/aaa" 注意不含根节点名(root)
     * @param eleValue 节点元素名
     * @throws ZanyException
     */
    public void setNodeText(String dictPath, String eleValue) throws ZanyException {
        Element tempEle = null, subEle = null;
        List list = null;
        int index = 2;
        try {
            String nodeName = StringUtils.GetItemfromStr(dictPath, index,PATHSPLIT);
            tempEle = transaction;
            while (!nodeName.equals("")) {
                subEle = null;
                list = tempEle.getChildren();
                for (Iterator it = list.iterator(); it.hasNext(); ) {
                    subEle = (Element) it.next();
                    if (subEle.getName().equals(nodeName)) {
                        break;
                    } else {
                        subEle = null;
                    }
                }
                if (subEle == null) {
                    subEle = new Element(nodeName);
                    tempEle.addContent(subEle);
                }
                index++;
                tempEle = subEle;
                nodeName = StringUtils.GetItemfromStr(dictPath, index,PATHSPLIT);
            }
            eleValue = eleValue == null || eleValue.equals("") ? " " : eleValue;
            subEle.addContent(eleValue);
        } catch (Exception e) {
            throw new ZanyException(ZanyErrorMsg.ERR_DEFAULT, "xml转化到字符串失败！\n"+e.getMessage(),e);
        }
    }

    /*
     * 根据dictPath路径插入节点
     * @param dictPath 节点路径 例如："/pub/aaa" 注意不含根节点名(root)
     * @param ele 节点元素
     * @throws ZanyException
     */
    public void setNode(String dictPath, Element ele) throws ZanyException {
        Element tempEle = null, subEle = null;
        List list = null;
        int index = 2;
        try {
            String nodeName = StringUtils.GetItemfromStr(dictPath, index, PATHSPLIT);
            tempEle = transaction;
            while (!nodeName.equals("")) {
                subEle = null;
                list = tempEle.getChildren();
                for (Iterator it = list.iterator(); it.hasNext(); ) {
                    subEle = (Element) it.next();
                    if (subEle.getName().equals(nodeName)) {
                        break;
                    }
                }
                if (subEle == null) {
                    subEle = new Element(nodeName);
                    tempEle.addContent(subEle);
                }
                index++;
                tempEle = subEle;
                nodeName = StringUtils.GetItemfromStr(dictPath, index,PATHSPLIT);
            }
            subEle.addContent(ele);
        } catch (Exception e) {
            throw new ZanyException(ZanyErrorMsg.ERR_DEFAULT, "xml转化到字符串失败！\n"+e.getMessage(),e);
        }
    }
	public static void main(String[] args){
	//String tempText="<root><head>fsdfds</head><datalist><data><userid>11</userid><username>ffee</username></data><data><userid>22</userid><username>fdse</username></data></datalist></root>";
		String tempText = "<transaction><header><ver>02</ver><msg><msgCd>HOUSE00101</msgCd><sndAppCd>HOUSE</sndAppCd><sndMbrCd>100000000000</sndMbrCd><sndDt>20111111</sndDt><sndTm>093047001</sndTm><rcvAppCd>MPS</rcvAppCd><rcvMbrCd>103100000018</rcvMbrCd><seqNb>00000000000000000010</seqNb><refSeqNb>00000000000000000011</refSeqNb><refMsgCd>HOUSE00100</refMsgCd><refSndAppCd>BANK</refSndAppCd><refSndMbrCd>103100000018</refSndMbrCd><refSndDt>20111111</refSndDt><refSndTm>093047001</refSndTm></msg><status><stscode>000000</stscode><stsdesc>成功</stsdesc></status></header><body><areaname>汉森金烁广场</areaname><groupid>01</groupid><unitid>01</unitid><doorid>102</doorid><planamt>2003.4</planamt><balance>0.0</balance></body></transaction>";
		try{ 
			XmlPkgImpl xml = new XmlPkgImpl(tempText);
			Map map=xml.getNodeMapHeader();
			System.out.println(map.get("msgCd"));
	    }catch(Exception e){
	       System.out.println(e.getMessage());
	    }     
	}
    
	public Map getNodeMapHeader() throws ZanyException {
	       Element tmpEle = null, parentEme = null, eMxUnit = null, childEme = null;
	       Map tmpMap = tmpMap = new HashMap();;
	       tmpEle = transaction;
	       parentEme = tmpEle.getChild("header");
	       List tmpList = parentEme.getChildren();
	       if ((tmpList != null) && (!tmpList.isEmpty())) {
	           for (int i = 0; i < tmpList.size(); i++) {
	               eMxUnit = (Element) tmpList.get(i);
	               List child = eMxUnit.getChildren();
	               if ((child != null) && (!child.isEmpty())) {
	                   for (int j = 0; j < child.size(); j++) {
	                       childEme = (Element) child.get(j);
	                       String name = childEme.getName();
	                       String value = childEme.getText();
	                       tmpMap.put(name, value);
	                   }
	               }
	           }
	       }
	       return tmpMap;
	 }
	
	public Map getNodeMapBody() throws ZanyException {
	       Element tmpEle = null, parentEme = null, eMxUnit = null, childEme = null;
	       Map tmpMap = tmpMap = new HashMap();;
	       tmpEle = transaction;
	       List tmpList = tmpEle.getChildren();
	       if ((tmpList != null) && (!tmpList.isEmpty())) {
	           for (int i = 0; i < tmpList.size(); i++) {
	               eMxUnit = (Element) tmpList.get(i);
	               List child = eMxUnit.getChildren();
	               if ((child != null) && (!child.isEmpty())) {
	                   for (int j = 0; j < child.size(); j++) {
	                       childEme = (Element) child.get(j);
	                       String name = childEme.getName();
	                       String value = childEme.getText();
	                       tmpMap.put(name, value);
	                   }
	               }
	           }
	       }
	       return tmpMap;
	 }
}
